home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / scope / 176-200 / scopedisk180 / arexxtutorial / rexxarplib / graph.rexx < prev    next >
OS/2 REXX Batch file  |  1995-03-19  |  9KB  |  304 lines

  1. /* 
  2. **         g r a p h . r e x x
  3. **  
  4. **  This is a simple graphing function that plots functions passed to it.
  5. **  It determines upper and lower limits for the function in the range to
  6. **  be plotted, and scales the graph accordingly. It determines a reasonable
  7. **  scale division to use and draws a grid. Wait till it's done plotting and
  8. **  then fiddle the sizing gadget!  Click on the close gadget to quit.
  9. **
  10. **  Calling sequence:
  11. **
  12. **       call graph(title, bins, xmin, xmax, function)
  13. **
  14. **  Arguments:
  15. **
  16. **       title      The string to put at the bottom of the graph
  17. **       bins       The number of horizontal samples to compute
  18. **       xmin       The starting X value
  19. **       xmax       The ending X value
  20. **       function   The function to compute. The function must be of
  21. **                  a single variable, x, and can otherwise only include
  22. **                  math functions and numerical constants. Be careful
  23. **                  and avoid specifying functions with singularities in
  24. **                  the plotting range.
  25. **
  26. **  Examples:
  27. **                    title        bins xmin xmax       function
  28. **
  29. **       call graph("exp(-x2)"    , 50, -2.5, 2.5, "30. * exp(-(x**2))")
  30. **       call graph("x3 + 2x - 13", 25, -2.5, 2.5, "x**3 + 2*x - 13"   )
  31. **       call graph("sin(x)"      , 25,  0.0, 6.3, "45. * sin(x)"      )
  32. **       call graph("log(x)"      , 25, 0.01, 5.0, "45. * log(x)"      )
  33. **
  34. **  By W.G.J. Langeveld, march 1989.
  35. */
  36.  
  37. /* trace r */
  38. parse arg tt, nn, xx, yy, ff
  39.  
  40. if ~show('l', "rexxarplib.library") then do
  41. check = addlib('rexxsupport.library',0,-30,0) 
  42. check = addlib('rexxmathlib.library',0,-30,0)
  43. check = addlib('rexxarplib.library',0,-30,0)   
  44. end
  45.  
  46. plot.bins  = nn
  47. plot.xmin  = xx
  48. plot.xmax  = yy
  49. plot.title = tt
  50.  
  51. delta = (plot.xmax - plot.xmin)/plot.bins
  52. x = plot.xmin
  53. do i = 0 to plot.bins
  54.    interpret "plot.i = "||ff
  55.    x = x + delta
  56. end
  57.  
  58. /*
  59. *   Determine the max and min of the curve
  60. */
  61. minval = plot.0
  62. maxval = plot.0
  63. do i = 1 to plot.bins
  64.    maxval = max(plot.i,maxval)
  65.    minval = min(plot.i,minval)
  66. end
  67.  
  68. /*
  69. *   Initial window sizes
  70. */
  71. window.leftedge = 50
  72. window.topedge  = 25
  73. window.width    = 300
  74. window.height   = 150
  75.  
  76. /*
  77. *   Set up a host.
  78. */
  79. address command runwsh "'call CreateHost(GRAPHHOST, GRAPHPORT)'"
  80. /*
  81. *   Wait for a while until host is ready.
  82. */
  83. do 50 while ~show('Ports','GRAPHHOST')
  84.    call delay 10  /* 200 ms */
  85.    end
  86.  
  87. /*
  88. *   Open the window
  89. */
  90. idcmp = 'CLOSEWINDOW+NEWSIZE'
  91. flags = 'WINDOWCLOSE+WINDOWDRAG+WINDOWDEPTH+WINDOWSIZING'
  92. call OpenWindow(GRAPHHOST, window.leftedge, window.topedge, window.width, ,
  93.                 window.height, idcmp, flags)
  94. /*
  95. *   Set NEWSIZE message to something useful
  96. */
  97. call ModifyHost(GRAPHHOST, NEWSIZE, "%w %h")
  98.  
  99. /* Open our host port */
  100. call openport(GRAPHPORT)
  101.  
  102. start:
  103. /*
  104. *   Make a drawing area
  105. */
  106. area.topedge    = min(0.1, 20/window.height)
  107. area.leftedge   = min(0.2, 60/window.width)
  108. area.width      = 1.0 - 2 * area.leftedge
  109. area.height     = 1.0 - 3 * area.topedge
  110. /*
  111. *   Draw the box outline of the plot
  112. */
  113. call SetAPen(GRAPHHOST, 3)
  114. call Move(GRAPHHOST, area.leftedge * window.width - 2,  ,
  115.                      area.topedge * window.height - 1)
  116. call Draw(GRAPHHOST, area.leftedge * window.width - 2,  ,
  117.                      (area.topedge + area.height) * window.height + 1)
  118. call Draw(GRAPHHOST, (area.leftedge + area.width) * window.width + 2,  ,
  119.                      (area.topedge + area.height) * window.height + 1)
  120. call Draw(GRAPHHOST, (area.leftedge + area.width) * window.width + 2,  ,
  121.                      area.topedge * window.height - 1)
  122. call Draw(GRAPHHOST, area.leftedge * window.width - 2,  ,
  123.                      area.topedge * window.height - 1)
  124.  
  125. /*
  126. *   Determine a nice grid to use. Try for 15 pixels heigh.
  127. */
  128. vticks = (window.height * area.height) % 15
  129. vscale = (maxval - minval) / vticks
  130. if vscale < 1 then
  131.    do
  132.       do imults = 1 until vscale > 1
  133.          vscale = vscale * 10
  134.       end
  135.       vscale = nint(vscale * 2) / 2
  136.       /* do i = 1 to imults
  137.          vscale = vscale / 10
  138.       end */
  139.       vscale = vscale / 10**imults
  140.    end
  141. else
  142.    do
  143.       do imults = 1 until vscale < 1
  144.          vscale = vscale / 10
  145.       end
  146.       vscale = vscale * 10
  147.       vscale = nint(vscale * 2) / 2
  148.       /* do i = 1 to imults - 1
  149.          vscale = vscale * 10
  150.       end */
  151.       vscale = vscale * 10**(imults-1)
  152.    end
  153.  
  154. /*
  155. *   ...and for 50 pixels wide
  156. */
  157. hticks = (window.width * area.width) % 50
  158. hscale = (plot.xmax - plot.xmin)/hticks
  159. if hscale < 1 then
  160.    do
  161.       do imults = 1 until hscale > 1
  162.          hscale = hscale * 10
  163.       end
  164.       hscale = nint(hscale * 2) / 2
  165.       /* do i = 1 to imults
  166.          hscale = hscale / 10
  167.       end */
  168.       hscale = hscale * 10**(-imults)
  169.    end
  170. else
  171.    do
  172.       do imults = 1 until hscale < 1
  173.          hscale = hscale / 10
  174.       end
  175.       hscale = hscale * 10
  176.       hscale = nint(hscale * 2) / 2
  177.       /* do i = 1 to imults - 1
  178.          hscale = hscale * 10
  179.       end */
  180.       hscale = hscale * 10**(imults-1)
  181.    end
  182.  
  183. /*
  184. *   Draw the grid and add scale text
  185. */
  186. ys = (minval % vscale) * vscale
  187. if ys < minval then ys = ys + vscale
  188. do while ys <= maxval
  189.    level = (area.topedge + area.height *   ,
  190.             (1.0 - (ys - minval) / (maxval - minval))) * window.height
  191.    call SetAPen(GRAPHHOST, 3) 
  192.    call SetDrPt(GRAPHHOST, c2d('C3C3C3C3'x))
  193.    call Move(GRAPHHOST, area.leftedge * window.width, level)
  194.    call Draw(GRAPHHOST, (area.leftedge + area.width) * window.width, level)
  195.  
  196.    call SetAPen(GRAPHHOST, 1) 
  197.    call SetDrPt(GRAPHHOST, c2d('FFFFFFFF'x))
  198.    call Move(GRAPHHOST, area.leftedge * window.width - 8 * length(ys) - 8,  ,
  199.                         level + 4)
  200.    call Text(GRAPHHOST, ys)
  201.    ys = ys + vscale
  202.    /* if ys > maxval then leave */
  203. end
  204.  
  205. /* trace off */
  206. xs = (plot.xmin % hscale) * hscale
  207. if xs < plot.xmin then xs = xs + hscale
  208. do while xs < plot.xmax
  209.    level = (area.leftedge + area.width *                 /* */ ,
  210.             ((xs - plot.xmin) / (plot.xmax - plot.xmin))) * window.width
  211.    call SetAPen(GRAPHHOST, 3) 
  212.    call SetDrPt(GRAPHHOST, c2d('C3C3C3C3'x))
  213.    call Move(GRAPHHOST, level, area.topedge * window.height)
  214.    call Draw(GRAPHHOST, level, (area.topedge + area.height) * window.height)
  215.  
  216.    call SetAPen(GRAPHHOST, 1) 
  217.    call SetDrPt(GRAPHHOST, c2d('FFFFFFFF'x))
  218.    call Move(GRAPHHOST, level - length(xs) * 4,          /* */ ,
  219.       (area.topedge + area.height) * window.height + 10)
  220.    call Text(GRAPHHOST, xs)
  221.    xs = xs + hscale
  222.    /* if xs > plot.xmax then leave */
  223. end
  224.  
  225. /*
  226. *   Draw the zero lines (if exist)
  227. */
  228. if minval <= 0 & maxval > 0 then do
  229.    zerolevel = (area.topedge + area.height *    ,
  230.                 (1.0 + minval / (maxval - minval))) * window.height
  231.    call SetAPen(GRAPHHOST, 2) 
  232.    call Move(GRAPHHOST, area.leftedge * window.width, zerolevel)
  233.    call Draw(GRAPHHOST, (area.leftedge + area.width) * window.width, zerolevel)
  234. end
  235.  
  236. if plot.xmin <= 0 & plot.xmax > 0 then
  237.    do
  238.       zerolevel = (area.leftedge - area.width *                /* */ ,
  239.                    (plot.xmin / (plot.xmax - plot.xmin))) * window.width
  240.       call SetAPen(GRAPHHOST, 2) 
  241.       call Move(GRAPHHOST, zerolevel, area.topedge * window.height)
  242.       call Draw(GRAPHHOST, zerolevel,                          /* */ ,
  243.                 (area.topedge + area.height) * window.height)
  244.    end
  245.  
  246. /*
  247. *   Plot the title
  248. */
  249. call SetAPen(GRAPHHOST, 1)
  250. call Move(GRAPHHOST,                                           /* */ ,
  251.   (area.leftedge + area.width / 2) * window.width - length(plot.title) * 4, ,
  252.   0.5 * (1.0 + area.topedge + area.height) * window.height + 10)
  253. call Text(GRAPHHOST, plot.title)
  254.  
  255. /*
  256. *   Draw the plot
  257. */
  258. call SetAPen(GRAPHHOST, 1)
  259. call Move(GRAPHHOST, area.leftedge * window.width,  ,
  260.    (area.topedge + area.height * (1.0 -             ,
  261.       (plot.0 - minval) / (maxval - minval))) * window.height)
  262. do i = 0 to plot.bins
  263.    call Draw(GRAPHHOST,                                              /* */ ,
  264.       (area.width * i / plot.bins + area.leftedge) * window.width,   /* */ ,
  265.       (area.topedge + area.height *                                  /* */ ,
  266.          (1.0 - (plot.i - minval) / (maxval - minval))) * window.height)
  267. end
  268.  
  269. /*
  270. *   Wait for messages at GRAPHPORT
  271. */
  272. quitflag = 0
  273. do forever until quitflag
  274.    call waitpkt(GRAPHPORT)
  275.    p = getpkt(GRAPHPORT)
  276.    if p ~== NULL() then
  277.       do
  278.  
  279.       thisarg = getarg(p)
  280.       t = reply(p, 0)
  281. /*
  282. *   Messages are either CLOSEWINDOW
  283. */
  284.       if thisarg == 'CLOSEWINDOW' then do
  285.          call CloseWindow(GRAPHHOST)
  286.          quitflag = 1
  287.       end
  288. /*
  289. *   ...or NEWSIZE
  290. */
  291.       else do
  292.          parse var thisarg xwidth xheight
  293.          window.width  = (xwidth % 10) * 10
  294.          window.height = (xheight % 10) * 10
  295.          call SetReqColor(GRAPHHOST, BACK, 0L)
  296.          call BackFill(GRAPHHOST)
  297.          signal start /* start over */
  298.       end
  299.    end
  300. end
  301.  
  302. exit
  303.  
  304.